﻿using System;
using System.IO;
using System.IO.Compression;
using System.Net;
using System.Text;
using System.Xml.Serialization;
using Pospa.NET.WebPageTestApi.DataObjects;
using Pospa.NET.WebPageTestApi.Extensions;
using Pospa.NET.WebPageTestApi.Interfaces;

namespace Pospa.NET.WebPageTestApi
{
	public class WebPageTestWorker : IWebPageTest
	{
		private const string SubmitTestEntryPoint = "runtest.php";
		private const string CheckTestEntryPoint = "testStatus.php";
		private const string AlternativeRawDataExtension = ".gz";

		private readonly Uri _webPageTestUrl;

		public WebPageTestWorker(Uri WebPageTestUrl)
		{
			_webPageTestUrl = WebPageTestUrl;
		}

		public ITestResponse SubmitTest(IBaseTestRequest testRequest, string requestId)
		{
			StringBuilder sb = new StringBuilder();
			sb.Append("?");
			sb.Append(string.Concat("url=", testRequest.Url.OriginalString.ToUrlEncoded()));
			sb.Append("&f=xml");
			sb.Append("&r=");
			sb.Append(requestId.ToUrlEncoded());
			if (testRequest is ITestRequest)
			{
				ITestRequest fullTestRequest = testRequest as ITestRequest;
				if (fullTestRequest.Runs.HasValue)
				{
					sb.Append(string.Concat("&runs=", fullTestRequest.Runs.Value));
				}
			}
			WebRequest request = WebRequest.Create(new Uri(_webPageTestUrl, string.Concat(SubmitTestEntryPoint, sb.ToString())));
			XmlSerializer serializer = new XmlSerializer(typeof (TestResponse));
			TestResponse response = (TestResponse) serializer.Deserialize(request.GetResponse().GetResponseStream());
			return response;
		}

		public ITestStatus CheckTest(string testId)
		{
			StringBuilder sb = new StringBuilder();
			sb.Append(string.Concat("?f=xml&test=", testId));
			WebRequest request = WebRequest.Create(new Uri(_webPageTestUrl, string.Concat(CheckTestEntryPoint, sb.ToString())));
			XmlSerializer serializer = new XmlSerializer(typeof (TestStatus));
			TestStatus response = (TestStatus) serializer.Deserialize(request.GetResponse().GetResponseStream());
			return response;
		}

		public ITestResult GetTestResult(ITestResponse test)
		{
			WebRequest request = WebRequest.Create(test.XmlUrl);
			XmlSerializer serializer = new XmlSerializer(typeof (TestResult));
			TestResult response = (TestResult) serializer.Deserialize(request.GetResponse().GetResponseStream());
			return response;
		}

		public string GetRawData(string url)
		{
			Stream responseStream = null;
			try
			{
				responseStream = WebRequest.Create(url).GetResponse().GetResponseStream();
			}
			catch (WebException ex)
			{
				responseStream =
					new GZipStream(
						WebRequest.Create(string.Concat(url, AlternativeRawDataExtension)).GetResponse().GetResponseStream(),
						CompressionMode.Decompress);
			}
			using (StreamReader sr = new StreamReader(responseStream))
			{
				return sr.ReadToEnd();
			}
		}
	}
}